﻿using System;
using System.Collections.Generic;
using System.IO;
using Terraria.ModLoader.Default;
using Terraria.ModLoader.Exceptions;

namespace Terraria.ModLoader.IO
{
	// Token: 0x020002C5 RID: 709
	public static class ItemIO
	{
		// Token: 0x06001BB9 RID: 7097 RVA: 0x00013EAC File Offset: 0x000120AC
		internal static void WriteVanillaID(Item item, BinaryWriter writer)
		{
			writer.Write((item.modItem != null) ? 0 : item.netID);
		}

		// Token: 0x06001BBA RID: 7098 RVA: 0x00431934 File Offset: 0x0042FB34
		public static TagCompound Save(Item item)
		{
			TagCompound tagCompound = new TagCompound();
			if (item.type <= 0)
			{
				return tagCompound;
			}
			if (item.modItem == null)
			{
				tagCompound.Set("mod", "Terraria");
				tagCompound.Set("id", item.netID);
			}
			else
			{
				tagCompound.Set("mod", item.modItem.mod.Name);
				tagCompound.Set("name", item.modItem.Name);
				tagCompound.Set("data", item.modItem.Save());
			}
			if (item.prefix != 0 && item.prefix < 84)
			{
				tagCompound.Set("prefix", item.prefix);
			}
			if (item.prefix >= 84)
			{
				ModPrefix prefix = ModPrefix.GetPrefix(item.prefix);
				tagCompound.Set("modPrefixMod", prefix.mod.Name);
				tagCompound.Set("modPrefixName", prefix.Name);
			}
			if (item.stack > 1)
			{
				tagCompound.Set("stack", item.stack);
			}
			if (item.favorited)
			{
				tagCompound.Set("fav", true);
			}
			tagCompound.Set("globalData", ItemIO.SaveGlobals(item));
			return tagCompound;
		}

		// Token: 0x06001BBB RID: 7099 RVA: 0x00431A78 File Offset: 0x0042FC78
		public static void Load(Item item, TagCompound tag)
		{
			if (tag.Count == 0)
			{
				item.netDefaults(0);
				return;
			}
			string @string = tag.GetString("mod");
			if (@string == "Terraria")
			{
				item.netDefaults(tag.GetInt("id"));
				if (tag.ContainsKey("legacyData"))
				{
					ItemIO.LoadLegacyModData(item, tag.GetByteArray("legacyData"), tag.GetBool("hasGlobalSaving"));
				}
			}
			else
			{
				Mod mod = ModLoader.GetMod(@string);
				int num = (mod != null) ? mod.ItemType(tag.GetString("name")) : 0;
				if (num > 0)
				{
					item.netDefaults(num);
					if (tag.ContainsKey("legacyData"))
					{
						ItemIO.LoadLegacyModData(item, tag.GetByteArray("legacyData"), tag.GetBool("hasGlobalSaving"));
					}
					else
					{
						item.modItem.Load(tag.GetCompound("data"));
					}
				}
				else
				{
					item.netDefaults(ModLoader.GetMod("ModLoader").ItemType("MysteryItem"));
					((MysteryItem)item.modItem).Setup(tag);
				}
			}
			item.Prefix((int)tag.GetByte("prefix"));
			if (tag.ContainsKey("modPrefixMod") && tag.ContainsKey("modPrefixName"))
			{
				string string2 = tag.GetString("modPrefixMod");
				string string3 = tag.GetString("modPrefixName");
				Mod mod2 = ModLoader.GetMod(string2);
				item.Prefix((int)((mod2 != null) ? mod2.PrefixType(string3) : 0));
			}
			item.stack = (tag.Get<int?>("stack") ?? 1);
			item.favorited = tag.GetBool("fav");
			if (!(item.modItem is MysteryItem))
			{
				ItemIO.LoadGlobals(item, tag.GetList<TagCompound>("globalData"));
			}
		}

		// Token: 0x06001BBC RID: 7100 RVA: 0x00431C3C File Offset: 0x0042FE3C
		public static Item Load(TagCompound tag)
		{
			Item item = new Item();
			ItemIO.Load(item, tag);
			return item;
		}

		// Token: 0x06001BBD RID: 7101 RVA: 0x00431C58 File Offset: 0x0042FE58
		internal static List<TagCompound> SaveGlobals(Item item)
		{
			if (item.modItem is MysteryItem)
			{
				return null;
			}
			List<TagCompound> list = new List<TagCompound>();
			foreach (GlobalItem globalItem in ItemLoader.globalItems)
			{
				GlobalItem globalItem2 = globalItem.Instance(item);
				if (globalItem2.NeedsSaving(item))
				{
					List<TagCompound> list2 = list;
					TagCompound tagCompound = new TagCompound();
					tagCompound["mod"] = globalItem2.mod.Name;
					tagCompound["name"] = globalItem2.Name;
					tagCompound["data"] = globalItem2.Save(item);
					list2.Add(tagCompound);
				}
			}
			if (list.Count <= 0)
			{
				return null;
			}
			return list;
		}

		// Token: 0x06001BBE RID: 7102 RVA: 0x00431D14 File Offset: 0x0042FF14
		internal static void LoadGlobals(Item item, IList<TagCompound> list)
		{
			foreach (TagCompound tagCompound in list)
			{
				Mod mod = ModLoader.GetMod(tagCompound.GetString("mod"));
				GlobalItem globalItem = (mod != null) ? mod.GetGlobalItem(tagCompound.GetString("name")) : null;
				if (globalItem != null)
				{
					GlobalItem globalItem2 = globalItem.Instance(item);
					try
					{
						globalItem2.Load(item, tagCompound.GetCompound("data"));
						continue;
					}
					catch (Exception inner)
					{
						throw new CustomModDataException(mod, "Error in reading custom player data for " + mod.Name, inner);
					}
				}
				item.GetGlobalItem<MysteryGlobalItem>(ModLoader.GetMod("ModLoader")).data.Add(tagCompound);
			}
		}

		// Token: 0x06001BBF RID: 7103 RVA: 0x00431DE8 File Offset: 0x0042FFE8
		public static void Send(Item item, BinaryWriter writer, bool writeStack = false, bool writeFavourite = false)
		{
			writer.Write((short)item.netID);
			writer.Write(item.prefix);
			if (writeStack)
			{
				writer.Write((short)item.stack);
			}
			if (writeFavourite)
			{
				writer.Write(item.favorited);
			}
			ItemIO.SendModData(item, writer);
		}

		// Token: 0x06001BC0 RID: 7104 RVA: 0x00013EC5 File Offset: 0x000120C5
		public static void Receive(Item item, BinaryReader reader, bool readStack = false, bool readFavorite = false)
		{
			item.netDefaults((int)reader.ReadInt16());
			item.Prefix((int)reader.ReadByte());
			if (readStack)
			{
				item.stack = (int)reader.ReadInt16();
			}
			if (readFavorite)
			{
				item.favorited = reader.ReadBoolean();
			}
			ItemIO.ReceiveModData(item, reader);
		}

		// Token: 0x06001BC1 RID: 7105 RVA: 0x00431E34 File Offset: 0x00430034
		public static Item Receive(BinaryReader reader, bool readStack = false, bool readFavorite = false)
		{
			Item item = new Item();
			ItemIO.Receive(item, reader, readStack, readFavorite);
			return item;
		}

		// Token: 0x06001BC2 RID: 7106 RVA: 0x00431E54 File Offset: 0x00430054
		public static void SendModData(Item item, BinaryWriter writer)
		{
			if (item.IsAir)
			{
				return;
			}
			writer.SafeWrite(delegate(BinaryWriter w)
			{
				ModItem modItem = item.modItem;
				if (modItem == null)
				{
					return;
				}
				modItem.NetSend(w);
			});
			GlobalItem[] netGlobals = ItemLoader.NetGlobals;
			for (int i = 0; i < netGlobals.Length; i++)
			{
				GlobalItem globalItem = netGlobals[i];
				writer.SafeWrite(delegate(BinaryWriter w)
				{
					globalItem.Instance(item).NetSend(item, w);
				});
			}
		}

		// Token: 0x06001BC3 RID: 7107 RVA: 0x00431ECC File Offset: 0x004300CC
		public static void ReceiveModData(Item item, BinaryReader reader)
		{
			if (item.IsAir)
			{
				return;
			}
			try
			{
				reader.SafeRead(delegate(BinaryReader r)
				{
					ModItem modItem = item.modItem;
					if (modItem == null)
					{
						return;
					}
					modItem.NetRecieve(r);
				});
			}
			catch (IOException)
			{
			}
			GlobalItem[] netGlobals = ItemLoader.NetGlobals;
			for (int i = 0; i < netGlobals.Length; i++)
			{
				GlobalItem globalItem = netGlobals[i];
				try
				{
					reader.SafeRead(delegate(BinaryReader r)
					{
						globalItem.Instance(item).NetReceive(item, r);
					});
				}
				catch (IOException)
				{
				}
			}
		}

		// Token: 0x06001BC4 RID: 7108 RVA: 0x00431F6C File Offset: 0x0043016C
		public static void LoadLegacy(Item item, BinaryReader reader, bool readStack = false, bool readFavorite = false)
		{
			string text = reader.ReadString();
			bool flag = false;
			if (text.Length == 0)
			{
				flag = true;
				text = reader.ReadString();
			}
			if (text == "Terraria")
			{
				item.netDefaults(reader.ReadInt32());
				ItemIO.LoadLegacyModData(item, ItemIO.LegacyModData(item.type, reader, flag), flag);
			}
			else
			{
				string text2 = reader.ReadString();
				Mod mod = ModLoader.GetMod(text);
				int num = (mod != null) ? mod.ItemType(text2) : 0;
				byte[] array = ItemIO.LegacyModData((num == 0) ? int.MaxValue : num, reader, flag);
				if (num != 0)
				{
					item.netDefaults(num);
					ItemIO.LoadLegacyModData(item, array, flag);
				}
				else
				{
					item.netDefaults(ModLoader.GetMod("ModLoader").ItemType("MysteryItem"));
					TagCompound tagCompound = new TagCompound();
					tagCompound["mod"] = text;
					tagCompound["name"] = text2;
					tagCompound["hasGlobalSaving"] = flag;
					tagCompound["legacyData"] = array;
					TagCompound tag = tagCompound;
					((MysteryItem)item.modItem).Setup(tag);
				}
			}
			item.Prefix((int)reader.ReadByte());
			if (readStack)
			{
				item.stack = reader.ReadInt32();
			}
			if (readFavorite)
			{
				item.favorited = reader.ReadBoolean();
			}
		}

		// Token: 0x06001BC5 RID: 7109 RVA: 0x004320A0 File Offset: 0x004302A0
		internal static byte[] LegacyModData(int type, BinaryReader reader, bool hasGlobalSaving = true)
		{
			byte[] result;
			using (MemoryStream memoryStream = new MemoryStream())
			{
				using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream))
				{
					if (type >= 3930)
					{
						ushort num = reader.ReadUInt16();
						binaryWriter.Write(num);
						binaryWriter.Write(reader.ReadBytes((int)num));
					}
					if (hasGlobalSaving)
					{
						ushort num2 = reader.ReadUInt16();
						binaryWriter.Write(num2);
						for (int i = 0; i < (int)num2; i++)
						{
							binaryWriter.Write(reader.ReadString());
							binaryWriter.Write(reader.ReadString());
							ushort num3 = reader.ReadUInt16();
							binaryWriter.Write(num3);
							binaryWriter.Write(reader.ReadBytes((int)num3));
						}
					}
				}
				result = memoryStream.ToArray();
			}
			return result;
		}

		// Token: 0x06001BC6 RID: 7110 RVA: 0x00432174 File Offset: 0x00430374
		internal static void LoadLegacyModData(Item item, byte[] data, bool hasGlobalSaving = true)
		{
			using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(data)))
			{
				if (item.modItem != null)
				{
					byte[] array = binaryReader.ReadBytes((int)binaryReader.ReadUInt16());
					if (array.Length != 0)
					{
						using (BinaryReader binaryReader2 = new BinaryReader(new MemoryStream(array)))
						{
							try
							{
								item.modItem.LoadLegacy(binaryReader2);
							}
							catch (Exception inner)
							{
								throw new CustomModDataException(item.modItem.mod, "Error in reading custom item data for " + item.modItem.mod.Name, inner);
							}
						}
					}
				}
				if (hasGlobalSaving)
				{
					int num = (int)binaryReader.ReadUInt16();
					for (int i = 0; i < num; i++)
					{
						string name = binaryReader.ReadString();
						string name2 = binaryReader.ReadString();
						byte[] array2 = binaryReader.ReadBytes((int)binaryReader.ReadUInt16());
						Mod mod = ModLoader.GetMod(name);
						GlobalItem globalItem = (mod != null) ? mod.GetGlobalItem(name2) : null;
						if (globalItem != null && array2.Length != 0)
						{
							using (BinaryReader binaryReader3 = new BinaryReader(new MemoryStream(array2)))
							{
								try
								{
									globalItem.LoadLegacy(item, binaryReader3);
								}
								catch (Exception inner2)
								{
									throw new CustomModDataException(globalItem.mod, "Error in reading custom global item data for " + globalItem.mod.Name, inner2);
								}
							}
						}
					}
				}
			}
		}

		// Token: 0x06001BC7 RID: 7111 RVA: 0x00432330 File Offset: 0x00430530
		public static void LoadLegacyInventory(Item[] inv, BinaryReader reader, bool readStack = false, bool readFavorite = false)
		{
			int num = (int)reader.ReadUInt16();
			for (int i = 0; i < num; i++)
			{
				ItemIO.LoadLegacy(inv[(int)reader.ReadUInt16()], reader, readStack, readFavorite);
			}
		}

		// Token: 0x06001BC8 RID: 7112 RVA: 0x00432360 File Offset: 0x00430560
		public static string ToBase64(Item item)
		{
			MemoryStream memoryStream = new MemoryStream();
			TagIO.ToStream(ItemIO.Save(item), memoryStream, true);
			return Convert.ToBase64String(memoryStream.ToArray());
		}

		// Token: 0x06001BC9 RID: 7113 RVA: 0x0043238C File Offset: 0x0043058C
		public static Item FromBase64(string base64)
		{
			MemoryStream stream = new MemoryStream(Convert.FromBase64String(base64));
			return ItemIO.Load(TagIO.FromStream(stream, true));
		}
	}
}
